// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: daniel

#pragma once

#include <memory>
#include <string>
#include <vector>

#include "coin2/exchange/base/api_base/asio_http_driver.h"
#include "coin2/exchange/base/order/processor.h"
#include "coin2/exchange/order/connection.pb.h"
#include "coin2/exchange/upbit/api_order/native_private_client.h"
#include "coin2/exchange/upbit/api_util/order_manager.h"

namespace coin2::exchange::order {
class UpbitRestParams;
}  // namespace coin2::exchange::order

namespace coin2::exchange::upbit::api_order {

class UpbitRestAsyncAsioSubscriber : public base::order::RestSubscriber {
 public:
  using RestParams = coin2::exchange::order::UpbitRestParams;
  using RestClient = UpbitNativePrivateClient;

 public:
  UpbitRestAsyncAsioSubscriber(
      coin2::exchange::base::order::NativePrivateClient* rest_client,
      coin2::exchange::base::api_base::NativeHttpAsioDriver* http_driver,
      const coin2::exchange::order::PrivateSubscriberConfig& config)
      : base::order::RestSubscriber(rest_client, http_driver, config) {
    order_mgr_ = std::make_unique<api_util::OrderManager>();
  }

  auto rest_client() { return dynamic_cast<RestClient*>(rest_client_); }
  void QueryBalance();
  void QueryOpenOrders();
  void QueryAllOrders(const std::string& state);
  void QueryFills();
  void SubscribeAsync() override;
  auto GetMutableOrderManager() -> api_util::OrderManager* { return order_mgr_.get(); }

 private:
  std::unique_ptr<api_util::OrderManager> order_mgr_ = {};
  const std::vector<std::string> all_states_ = {"wait", "done", "cancel"};
  bool query_fill_in_progress_ = false;
};

}  // namespace coin2::exchange::upbit::api_order
